
// Copyright (C) 2010-2011 Luca Piccioni
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//  
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//  
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Text;

using Derm.Raster;

namespace Derm.Render
{
	/// <summary>
	/// Font resource.
	/// </summary>
	/// <remarks>
	/// This class encapsulate every information required to properly render a font.
	/// </remarks>
	class FontResource : RenderResource
	{
		#region Constructors

		/// <summary>
		/// Construct a FontResource specifying family, size and styles.
		/// </summary>
		/// <param name="family">
		/// A <see cref="System.String"/> that specifies the font family. The family
		/// name shall be registered on the current host system.
		/// </param>
		/// <param name="size">
		/// A <see cref="System.UInt32"/> that specifies the font size.
		/// </param>
		/// <param name="styles">
		/// A <see cref="FontStyle"/> that specifies supported font styles.
		/// </param>
		private FontResource(string family, uint size, FontStyle styles)
		{
			if (String.IsNullOrEmpty(family))
				throw new ArgumentException("invalid family", "family");
			if (size == 0)
				throw new ArgumentException("zero size not allowed", "size");

			mFamily = family;
			mSize = size;
			mStyles = styles;

			mFontGlyphImage = FontGlyphImage.Create(family, size, styles);
		}

		#endregion

		#region Font Definition

		/// <summary>
		/// Font family.
		/// </summary>
		public string Family { get { return (mFamily); } }

		/// <summary>
		/// Font size.
		/// </summary>
		public uint Size { get { return (mSize); } }

		/// <summary>
		/// Font styles.
		/// </summary>
		public FontStyle Style { get { return (mStyles); } }

		/// <summary>
		/// Font family name.
		/// </summary>
		private readonly string mFamily;

		/// <summary>
		/// Font size.
		/// </summary>
		private readonly uint mSize;

		/// <summary>
		/// Font styles.
		/// </summary>
		private readonly FontStyle mStyles = FontStyle.None;

		#endregion

		#region Font Resources

		/// <summary>
		/// Texture used for font rendering.
		/// </summary>
		public Texture2d FontTexture { get { return (mFontTexture); } }

		public FontGlyphImage FontGlyphInfo { get { return (mFontGlyphImage); } }

		/// <summary>
		/// Glyph image and coordinates.
		/// </summary>
		private readonly FontGlyphImage mFontGlyphImage;

		/// <summary>
		/// Texture used for rendering font glyphs.
		/// </summary>
		private Texture2d mFontTexture;

		#endregion

		#region Font Factory

		public static FontResource Create(string family, uint size, FontStyle styles)
		{
			return (new FontResource(family, size, styles));
		}

		#endregion

		#region RenderResource Overrides

		/// <summary>
		/// RenderResource object class.
		/// </summary>
		internal static readonly Guid FontResourceObjectClass = new Guid("0D9D62A8-CD18-4922-800F-72BEE41A96D1");

		/// <summary>
		/// RenderResource object class.
		/// </summary>
		public override Guid ObjectClass { get { return (FontResourceObjectClass); } }

		/// <summary>
		/// Create a RenderResource name.
		/// </summary>
		/// <param name="ctx">
		/// A <see cref="RenderContext"/> used for creating this object name.
		/// </param>
		/// <returns>
		/// It returns a valid object name for this RenderResource.
		/// </returns>
		protected override uint CreateName(RenderContext ctx)
		{
			return (1);
		}

		/// <summary>
		/// Actually create this RenderResource resources.
		/// </summary>
		/// <param name="ctx">
		/// A <see cref="RenderContext"/> used for allocating resources.
		/// </param>
		/// <remarks>
		/// This method actually do:
		/// - Create font texture
		/// </remarks>
		protected override void CreateObject(RenderContext ctx)
		{
			// Create font texture
			mFontTexture = new Texture2d();
			mFontTexture.Create(ctx, mFontGlyphImage.GlyphImage);
		}

		#endregion
	}
}